home *** CD-ROM | disk | FTP | other *** search
/ MPEG Toolkit / MPEG Toolkit.iso / os2 / mpegenc / src / subsampl.c < prev   
C/C++ Source or Header  |  1997-01-01  |  30KB  |  778 lines

  1. /*===========================================================================*
  2.  * subsample.c                                     *
  3.  *                                         *
  4.  *    Procedures concerned with subsampling                     *
  5.  *                                         *
  6.  * EXPORTED PROCEDURES:                                 *
  7.  *    LumMotionErrorA                                 *
  8.  *    LumMotionErrorB                                 *
  9.  *    LumMotionErrorC                                 *
  10.  *    LumMotionErrorD                                 *
  11.  *                                         *
  12.  *===========================================================================*/
  13.  
  14. /*
  15.  * Copyright (c) 1993 The Regents of the University of California.
  16.  * All rights reserved.
  17.  *
  18.  * Permission to use, copy, modify, and distribute this software and its
  19.  * documentation for any purpose, without fee, and without written agreement is
  20.  * hereby granted, provided that the above copyright notice and the following
  21.  * two paragraphs appear in all copies of this software.
  22.  *
  23.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  24.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  25.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  26.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  *
  28.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  29.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  30.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  31.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  32.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  33.  */
  34.  
  35. /*  
  36.  *  $Header: /n/picasso/users/keving/encode/src/RCS/subsample.c,v 1.3 1993/07/22 22:23:43 keving Exp keving $
  37.  *  $Log: subsample.c,v $
  38.  * Revision 1.3  1993/07/22  22:23:43  keving
  39.  * nothing
  40.  *
  41.  * Revision 1.2  1993/06/30  20:06:09  keving
  42.  * nothing
  43.  *
  44.  * Revision 1.1  1993/06/22  21:56:05  keving
  45.  * nothing
  46.  *
  47.  */
  48.  
  49.  
  50. /*==============*
  51.  * HEADER FILES *
  52.  *==============*/
  53.  
  54. #include "all.h"
  55. #include "mtypes.h"
  56. #include "frames.h"
  57. #include "bitio.h"
  58. #ifdef OS2
  59. /* @@@ FAT 8.3 convention */
  60. #include "prototyp.h"
  61. #else
  62. #include "prototypes.h"
  63. #endif
  64.  
  65. #undef ABS
  66. #define ABS(x)    ((x < 0) ? (-x) : x)
  67.  
  68.  
  69. /*=====================*
  70.  * EXPORTED PROCEDURES *
  71.  *=====================*/
  72.  
  73.  
  74. /*===========================================================================*
  75.  *
  76.  * LumMotionErrorA
  77.  *
  78.  *    compute the motion error for the A subsampling pattern
  79.  *
  80.  * RETURNS:    the error, or some number greater if it is worse
  81.  *
  82.  * SIDE EFFECTS:    none
  83.  *
  84.  *===========================================================================*/
  85. int32
  86. LumMotionErrorA(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
  87.     LumBlock currentBlock;
  88.     MpegFrame *prevFrame;
  89.     int by;
  90.     int bx;
  91.     int my;
  92.     int mx;
  93.     int32 bestSoFar;
  94. {
  95.     register int32    diff = 0;        /* max value of diff is 255*256 = 65280 */
  96.     register int32 localDiff;
  97.     register uint8 *macross;
  98.     register uint8 **prev;
  99.     register int    fy, fx;
  100.     boolean xHalf, yHalf;
  101.  
  102.     xHalf = (ABS(mx) % 2 == 1);
  103.     yHalf = (ABS(my) % 2 == 1);
  104.  
  105.     MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
  106.  
  107.     if ( xHalf ) {
  108.     if ( mx < 0 ) {
  109.         fx--;
  110.     }
  111.  
  112.     if ( yHalf ) {
  113.         if ( my < 0 ) {
  114.         fy--;
  115.         }
  116.         
  117.         prev = prevFrame->halfBoth;
  118.     } else {
  119.         prev = prevFrame->halfX;
  120.     }
  121.     } else if ( yHalf ) {
  122.     if ( my < 0 ) {
  123.         fy--;
  124.     }
  125.  
  126.     prev = prevFrame->halfY;
  127.     } else {
  128.     prev = prevFrame->ref_y;
  129.     }
  130.  
  131.     macross = &(prev[fy][fx]);
  132.  
  133.     localDiff = macross[0]-currentBlock[0][0];     diff += ABS(localDiff);
  134.     localDiff = macross[2]-currentBlock[0][2];     diff += ABS(localDiff);
  135.     localDiff = macross[4]-currentBlock[0][4];     diff += ABS(localDiff);
  136.     localDiff = macross[6]-currentBlock[0][6];     diff += ABS(localDiff);
  137.     localDiff = macross[8]-currentBlock[0][8];     diff += ABS(localDiff);
  138.     localDiff = macross[10]-currentBlock[0][10];     diff += ABS(localDiff);
  139.     localDiff = macross[12]-currentBlock[0][12];     diff += ABS(localDiff);
  140.     localDiff = macross[14]-currentBlock[0][14];     diff += ABS(localDiff);
  141.  
  142.     if ( diff > bestSoFar ) {
  143.     return diff;
  144.     }
  145.  
  146.     macross = &(prev[fy+2][fx]);
  147.  
  148.     localDiff = macross[0]-currentBlock[2][0];     diff += ABS(localDiff);
  149.     localDiff = macross[2]-currentBlock[2][2];     diff += ABS(localDiff);
  150.     localDiff = macross[4]-currentBlock[2][4];     diff += ABS(localDiff);
  151.     localDiff = macross[6]-currentBlock[2][6];     diff += ABS(localDiff);
  152.     localDiff = macross[8]-currentBlock[2][8];     diff += ABS(localDiff);
  153.     localDiff = macross[10]-currentBlock[2][10];     diff += ABS(localDiff);
  154.     localDiff = macross[12]-currentBlock[2][12];     diff += ABS(localDiff);
  155.     localDiff = macross[14]-currentBlock[2][14];     diff += ABS(localDiff);
  156.  
  157.     if ( diff > bestSoFar ) {
  158.     return diff;
  159.     }
  160.  
  161.     macross = &(prev[fy+4][fx]);
  162.  
  163.     localDiff = macross[0]-currentBlock[4][0];     diff += ABS(localDiff);
  164.     localDiff = macross[2]-currentBlock[4][2];     diff += ABS(localDiff);
  165.     localDiff = macross[4]-currentBlock[4][4];     diff += ABS(localDiff);
  166.     localDiff = macross[6]-currentBlock[4][6];     diff += ABS(localDiff);
  167.     localDiff = macross[8]-currentBlock[4][8];     diff += ABS(localDiff);
  168.     localDiff = macross[10]-currentBlock[4][10];     diff += ABS(localDiff);
  169.     localDiff = macross[12]-currentBlock[4][12];     diff += ABS(localDiff);
  170.     localDiff = macross[14]-currentBlock[4][14];     diff += ABS(localDiff);
  171.  
  172.     if ( diff > bestSoFar ) {
  173.     return diff;
  174.     }
  175.  
  176.     macross = &(prev[fy+6][fx]);
  177.  
  178.     localDiff = macross[0]-currentBlock[6][0];     diff += ABS(localDiff);
  179.     localDiff = macross[2]-currentBlock[6][2];     diff += ABS(localDiff);
  180.     localDiff = macross[4]-currentBlock[6][4];     diff += ABS(localDiff);
  181.     localDiff = macross[6]-currentBlock[6][6];     diff += ABS(localDiff);
  182.     localDiff = macross[8]-currentBlock[6][8];     diff += ABS(localDiff);
  183.     localDiff = macross[10]-currentBlock[6][10];     diff += ABS(localDiff);
  184.     localDiff = macross[12]-currentBlock[6][12];     diff += ABS(localDiff);
  185.     localDiff = macross[14]-currentBlock[6][14];     diff += ABS(localDiff);
  186.  
  187.     if ( diff > bestSoFar ) {
  188.     return diff;
  189.     }
  190.  
  191.     macross = &(prev[fy+8][fx]);
  192.  
  193.     localDiff = macross[0]-currentBlock[8][0];     diff += ABS(localDiff);
  194.     localDiff = macross[2]-currentBlock[8][2];     diff += ABS(localDiff);
  195.     localDiff = macross[4]-currentBlock[8][4];     diff += ABS(localDiff);
  196.     localDiff = macross[6]-currentBlock[8][6];     diff += ABS(localDiff);
  197.     localDiff = macross[8]-currentBlock[8][8];     diff += ABS(localDiff);
  198.     localDiff = macross[10]-currentBlock[8][10];     diff += ABS(localDiff);
  199.     localDiff = macross[12]-currentBlock[8][12];     diff += ABS(localDiff);
  200.     localDiff = macross[14]-currentBlock[8][14];     diff += ABS(localDiff);
  201.  
  202.     if ( diff > bestSoFar ) {
  203.     return diff;
  204.     }
  205.  
  206.     macross = &(prev[fy+10][fx]);
  207.  
  208.     localDiff = macross[0]-currentBlock[10][0];     diff += ABS(localDiff);
  209.     localDiff = macross[2]-currentBlock[10][2];     diff += ABS(localDiff);
  210.     localDiff = macross[4]-currentBlock[10][4];     diff += ABS(localDiff);
  211.     localDiff = macross[6]-currentBlock[10][6];     diff += ABS(localDiff);
  212.     localDiff = macross[8]-currentBlock[10][8];     diff += ABS(localDiff);
  213.     localDiff = macross[10]-currentBlock[10][10];     diff += ABS(localDiff);
  214.     localDiff = macross[12]-currentBlock[10][12];     diff += ABS(localDiff);
  215.     localDiff = macross[14]-currentBlock[10][14];     diff += ABS(localDiff);
  216.  
  217.     if ( diff > bestSoFar ) {
  218.     return diff;
  219.     }
  220.  
  221.     macross = &(prev[fy+12][fx]);
  222.  
  223.     localDiff = macross[0]-currentBlock[12][0];     diff += ABS(localDiff);
  224.     localDiff = macross[2]-currentBlock[12][2];     diff += ABS(localDiff);
  225.     localDiff = macross[4]-currentBlock[12][4];     diff += ABS(localDiff);
  226.     localDiff = macross[6]-currentBlock[12][6];     diff += ABS(localDiff);
  227.     localDiff = macross[8]-currentBlock[12][8];     diff += ABS(localDiff);
  228.     localDiff = macross[10]-currentBlock[12][10];     diff += ABS(localDiff);
  229.     localDiff = macross[12]-currentBlock[12][12];     diff += ABS(localDiff);
  230.     localDiff = macross[14]-currentBlock[12][14];     diff += ABS(localDiff);
  231.  
  232.     if ( diff > bestSoFar ) {
  233.     return diff;
  234.     }
  235.  
  236.     macross = &(prev[fy+14][fx]);
  237.  
  238.     localDiff = macross[0]-currentBlock[14][0];     diff += ABS(localDiff);
  239.     localDiff = macross[2]-currentBlock[14][2];     diff += ABS(localDiff);
  240.     localDiff = macross[4]-currentBlock[14][4];     diff += ABS(localDiff);
  241.     localDiff = macross[6]-currentBlock[14][6];     diff += ABS(localDiff);
  242.     localDiff = macross[8]-currentBlock[14][8];     diff += ABS(localDiff);
  243.     localDiff = macross[10]-currentBlock[14][10];     diff += ABS(localDiff);
  244.     localDiff = macross[12]-currentBlock[14][12];     diff += ABS(localDiff);
  245.     localDiff = macross[14]-currentBlock[14][14];     diff += ABS(localDiff);
  246.  
  247.     return diff;
  248. }
  249.  
  250.  
  251. /*===========================================================================*
  252.  *
  253.  * LumMotionErrorB
  254.  *
  255.  *    compute the motion error for the B subsampling pattern
  256.  *
  257.  * RETURNS:    the error, or some number greater if it is worse
  258.  *
  259.  * SIDE EFFECTS:    none
  260.  *
  261.  *===========================================================================*/
  262. int32
  263. LumMotionErrorB(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
  264.     LumBlock currentBlock;
  265.     MpegFrame *prevFrame;
  266.     int by;
  267.     int bx;
  268.     int my;
  269.     int mx;
  270.     int32 bestSoFar;
  271. {
  272.     register int32    diff = 0;        /* max value of diff is 255*256 = 65280 */
  273.     register int32 localDiff;
  274.     register uint8 *macross;
  275.     register uint8 **prev;
  276.     register int    fy, fx;
  277.     boolean xHalf, yHalf;
  278.  
  279.     xHalf = (ABS(mx) % 2 == 1);
  280.     yHalf = (ABS(my) % 2 == 1);
  281.  
  282.     MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
  283.  
  284.     if ( xHalf ) {
  285.     if ( mx < 0 ) {
  286.         fx--;
  287.     }
  288.  
  289.     if ( yHalf ) {
  290.         if ( my < 0 ) {
  291.         fy--;
  292.         }
  293.         
  294.         prev = prevFrame->halfBoth;
  295.     } else {
  296.         prev = prevFrame->halfX;
  297.     }
  298.     } else if ( yHalf ) {
  299.     if ( my < 0 ) {
  300.         fy--;
  301.     }
  302.  
  303.     prev = prevFrame->halfY;
  304.     } else {
  305.     prev = prevFrame->ref_y;
  306.     }
  307.  
  308.     macross = &(prev[fy+0][fx]);
  309.  
  310.     localDiff = macross[1]-currentBlock[0][1];     diff += ABS(localDiff);
  311.     localDiff = macross[3]-currentBlock[0][3];     diff += ABS(localDiff);
  312.     localDiff = macross[5]-currentBlock[0][5];     diff += ABS(localDiff);
  313.     localDiff = macross[7]-currentBlock[0][7];     diff += ABS(localDiff);
  314.     localDiff = macross[9]-currentBlock[0][9];     diff += ABS(localDiff);
  315.     localDiff = macross[11]-currentBlock[0][11];     diff += ABS(localDiff);
  316.     localDiff = macross[13]-currentBlock[0][13];     diff += ABS(localDiff);
  317.     localDiff = macross[15]-currentBlock[0][15];     diff += ABS(localDiff);
  318.  
  319.     if ( diff > bestSoFar ) {
  320.     return diff;
  321.     }
  322.  
  323.     macross = &(prev[fy+2][fx]);
  324.  
  325.     localDiff = macross[1]-currentBlock[2][1];     diff += ABS(localDiff);
  326.     localDiff = macross[3]-currentBlock[2][3];     diff += ABS(localDiff);
  327.     localDiff = macross[5]-currentBlock[2][5];     diff += ABS(localDiff);
  328.     localDiff = macross[7]-currentBlock[2][7];     diff += ABS(localDiff);
  329.     localDiff = macross[9]-currentBlock[2][9];     diff += ABS(localDiff);
  330.     localDiff = macross[11]-currentBlock[2][11];     diff += ABS(localDiff);
  331.     localDiff = macross[13]-currentBlock[2][13];     diff += ABS(localDiff);
  332.     localDiff = macross[15]-currentBlock[2][15];     diff += ABS(localDiff);
  333.  
  334.     if ( diff > bestSoFar ) {
  335.     return diff;
  336.     }
  337.  
  338.     macross = &(prev[fy+4][fx]);
  339.  
  340.     localDiff = macross[1]-currentBlock[4][1];     diff += ABS(localDiff);
  341.     localDiff = macross[3]-currentBlock[4][3];     diff += ABS(localDiff);
  342.     localDiff = macross[5]-currentBlock[4][5];     diff += ABS(localDiff);
  343.     localDiff = macross[7]-currentBlock[4][7];     diff += ABS(localDiff);
  344.     localDiff = macross[9]-currentBlock[4][9];     diff += ABS(localDiff);
  345.     localDiff = macross[11]-currentBlock[4][11];     diff += ABS(localDiff);
  346.     localDiff = macross[13]-currentBlock[4][13];     diff += ABS(localDiff);
  347.     localDiff = macross[15]-currentBlock[4][15];     diff += ABS(localDiff);
  348.  
  349.     if ( diff > bestSoFar ) {
  350.     return diff;
  351.     }
  352.  
  353.     macross = &(prev[fy+6][fx]);
  354.  
  355.     localDiff = macross[1]-currentBlock[6][1];     diff += ABS(localDiff);
  356.     localDiff = macross[3]-currentBlock[6][3];     diff += ABS(localDiff);
  357.     localDiff = macross[5]-currentBlock[6][5];     diff += ABS(localDiff);
  358.     localDiff = macross[7]-currentBlock[6][7];     diff += ABS(localDiff);
  359.     localDiff = macross[9]-currentBlock[6][9];     diff += ABS(localDiff);
  360.     localDiff = macross[11]-currentBlock[6][11];     diff += ABS(localDiff);
  361.     localDiff = macross[13]-currentBlock[6][13];     diff += ABS(localDiff);
  362.     localDiff = macross[15]-currentBlock[6][15];     diff += ABS(localDiff);
  363.  
  364.     if ( diff > bestSoFar ) {
  365.     return diff;
  366.     }
  367.  
  368.     macross = &(prev[fy+8][fx]);
  369.  
  370.     localDiff = macross[1]-currentBlock[8][1];     diff += ABS(localDiff);
  371.     localDiff = macross[3]-currentBlock[8][3];     diff += ABS(localDiff);
  372.     localDiff = macross[5]-currentBlock[8][5];     diff += ABS(localDiff);
  373.     localDiff = macross[7]-currentBlock[8][7];     diff += ABS(localDiff);
  374.     localDiff = macross[9]-currentBlock[8][9];     diff += ABS(localDiff);
  375.     localDiff = macross[11]-currentBlock[8][11];     diff += ABS(localDiff);
  376.     localDiff = macross[13]-currentBlock[8][13];     diff += ABS(localDiff);
  377.     localDiff = macross[15]-currentBlock[8][15];     diff += ABS(localDiff);
  378.  
  379.     if ( diff > bestSoFar ) {
  380.     return diff;
  381.     }
  382.  
  383.     macross = &(prev[fy+10][fx]);
  384.  
  385.     localDiff = macross[1]-currentBlock[10][1];     diff += ABS(localDiff);
  386.     localDiff = macross[3]-currentBlock[10][3];     diff += ABS(localDiff);
  387.     localDiff = macross[5]-currentBlock[10][5];     diff += ABS(localDiff);
  388.     localDiff = macross[7]-currentBlock[10][7];     diff += ABS(localDiff);
  389.     localDiff = macross[9]-currentBlock[10][9];     diff += ABS(localDiff);
  390.     localDiff = macross[11]-currentBlock[10][11];     diff += ABS(localDiff);
  391.     localDiff = macross[13]-currentBlock[10][13];     diff += ABS(localDiff);
  392.     localDiff = macross[15]-currentBlock[10][15];     diff += ABS(localDiff);
  393.  
  394.     if ( diff > bestSoFar ) {
  395.     return diff;
  396.     }
  397.  
  398.     macross = &(prev[fy+12][fx]);
  399.  
  400.     localDiff = macross[1]-currentBlock[12][1];     diff += ABS(localDiff);
  401.     localDiff = macross[3]-currentBlock[12][3];     diff += ABS(localDiff);
  402.     localDiff = macross[5]-currentBlock[12][5];     diff += ABS(localDiff);
  403.     localDiff = macross[7]-currentBlock[12][7];     diff += ABS(localDiff);
  404.     localDiff = macross[9]-currentBlock[12][9];     diff += ABS(localDiff);
  405.     localDiff = macross[11]-currentBlock[12][11];     diff += ABS(localDiff);
  406.     localDiff = macross[13]-currentBlock[12][13];     diff += ABS(localDiff);
  407.     localDiff = macross[15]-currentBlock[12][15];     diff += ABS(localDiff);
  408.  
  409.     if ( diff > bestSoFar ) {
  410.     return diff;
  411.     }
  412.  
  413.     macross = &(prev[fy+14][fx]);
  414.  
  415.     localDiff = macross[1]-currentBlock[14][1];     diff += ABS(localDiff);
  416.     localDiff = macross[3]-currentBlock[14][3];     diff += ABS(localDiff);
  417.     localDiff = macross[5]-currentBlock[14][5];     diff += ABS(localDiff);
  418.     localDiff = macross[7]-currentBlock[14][7];     diff += ABS(localDiff);
  419.     localDiff = macross[9]-currentBlock[14][9];     diff += ABS(localDiff);
  420.     localDiff = macross[11]-currentBlock[14][11];     diff += ABS(localDiff);
  421.     localDiff = macross[13]-currentBlock[14][13];     diff += ABS(localDiff);
  422.     localDiff = macross[15]-currentBlock[14][15];     diff += ABS(localDiff);
  423.  
  424.     return diff;
  425. }
  426.  
  427.  
  428. /*===========================================================================*
  429.  *
  430.  * LumMotionErrorC
  431.  *
  432.  *    compute the motion error for the C subsampling pattern
  433.  *
  434.  * RETURNS:    the error, or some number greater if it is worse
  435.  *
  436.  * SIDE EFFECTS:    none
  437.  *
  438.  *===========================================================================*/
  439. int32
  440. LumMotionErrorC(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
  441.     LumBlock currentBlock;
  442.     MpegFrame *prevFrame;
  443.     int by;
  444.     int bx;
  445.     int my;
  446.     int mx;
  447.     int32 bestSoFar;
  448. {
  449.     register int32    diff = 0;        /* max value of diff is 255*256 = 65280 */
  450.     register int32 localDiff;
  451.     register uint8 *macross;
  452.     register uint8 **prev;
  453.     register int    fy, fx;
  454.     boolean xHalf, yHalf;
  455.  
  456.     xHalf = (ABS(mx) % 2 == 1);
  457.     yHalf = (ABS(my) % 2 == 1);
  458.  
  459.     MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
  460.  
  461.     if ( xHalf ) {
  462.     if ( mx < 0 ) {
  463.         fx--;
  464.     }
  465.  
  466.     if ( yHalf ) {
  467.         if ( my < 0 ) {
  468.         fy--;
  469.         }
  470.         
  471.         prev = prevFrame->halfBoth;
  472.     } else {
  473.         prev = prevFrame->halfX;
  474.     }
  475.     } else if ( yHalf ) {
  476.     if ( my < 0 ) {
  477.         fy--;
  478.     }
  479.  
  480.     prev = prevFrame->halfY;
  481.     } else {
  482.     prev = prevFrame->ref_y;
  483.     }
  484.  
  485.     macross = &(prev[fy+1][fx]);
  486.  
  487.     localDiff = macross[0]-currentBlock[1][0];     diff += ABS(localDiff);
  488.     localDiff = macross[2]-currentBlock[1][2];     diff += ABS(localDiff);
  489.     localDiff = macross[4]-currentBlock[1][4];     diff += ABS(localDiff);
  490.     localDiff = macross[6]-currentBlock[1][6];     diff += ABS(localDiff);
  491.     localDiff = macross[8]-currentBlock[1][8];     diff += ABS(localDiff);
  492.     localDiff = macross[10]-currentBlock[1][10];     diff += ABS(localDiff);
  493.     localDiff = macross[12]-currentBlock[1][12];     diff += ABS(localDiff);
  494.     localDiff = macross[14]-currentBlock[1][14];     diff += ABS(localDiff);
  495.  
  496.     if ( diff > bestSoFar ) {
  497.     return diff;
  498.     }
  499.  
  500.     macross = &(prev[fy+3][fx]);
  501.  
  502.     localDiff = macross[0]-currentBlock[3][0];     diff += ABS(localDiff);
  503.     localDiff = macross[2]-currentBlock[3][2];     diff += ABS(localDiff);
  504.     localDiff = macross[4]-currentBlock[3][4];     diff += ABS(localDiff);
  505.     localDiff = macross[6]-currentBlock[3][6];     diff += ABS(localDiff);
  506.     localDiff = macross[8]-currentBlock[3][8];     diff += ABS(localDiff);
  507.     localDiff = macross[10]-currentBlock[3][10];     diff += ABS(localDiff);
  508.     localDiff = macross[12]-currentBlock[3][12];     diff += ABS(localDiff);
  509.     localDiff = macross[14]-currentBlock[3][14];     diff += ABS(localDiff);
  510.  
  511.     if ( diff > bestSoFar ) {
  512.     return diff;
  513.     }
  514.  
  515.     macross = &(prev[fy+5][fx]);
  516.  
  517.     localDiff = macross[0]-currentBlock[5][0];     diff += ABS(localDiff);
  518.     localDiff = macross[2]-currentBlock[5][2];     diff += ABS(localDiff);
  519.     localDiff = macross[4]-currentBlock[5][4];     diff += ABS(localDiff);
  520.     localDiff = macross[6]-currentBlock[5][6];     diff += ABS(localDiff);
  521.     localDiff = macross[8]-currentBlock[5][8];     diff += ABS(localDiff);
  522.     localDiff = macross[10]-currentBlock[5][10];     diff += ABS(localDiff);
  523.     localDiff = macross[12]-currentBlock[5][12];     diff += ABS(localDiff);
  524.     localDiff = macross[14]-currentBlock[5][14];     diff += ABS(localDiff);
  525.  
  526.     if ( diff > bestSoFar ) {
  527.     return diff;
  528.     }
  529.  
  530.     macross = &(prev[fy+7][fx]);
  531.  
  532.     localDiff = macross[0]-currentBlock[7][0];     diff += ABS(localDiff);
  533.     localDiff = macross[2]-currentBlock[7][2];     diff += ABS(localDiff);
  534.     localDiff = macross[4]-currentBlock[7][4];     diff += ABS(localDiff);
  535.     localDiff = macross[6]-currentBlock[7][6];     diff += ABS(localDiff);
  536.     localDiff = macross[8]-currentBlock[7][8];     diff += ABS(localDiff);
  537.     localDiff = macross[10]-currentBlock[7][10];     diff += ABS(localDiff);
  538.     localDiff = macross[12]-currentBlock[7][12];     diff += ABS(localDiff);
  539.     localDiff = macross[14]-currentBlock[7][14];     diff += ABS(localDiff);
  540.  
  541.     if ( diff > bestSoFar ) {
  542.     return diff;
  543.     }
  544.  
  545.     macross = &(prev[fy+9][fx]);
  546.  
  547.     localDiff = macross[0]-currentBlock[9][0];     diff += ABS(localDiff);
  548.     localDiff = macross[2]-currentBlock[9][2];     diff += ABS(localDiff);
  549.     localDiff = macross[4]-currentBlock[9][4];     diff += ABS(localDiff);
  550.     localDiff = macross[6]-currentBlock[9][6];     diff += ABS(localDiff);
  551.     localDiff = macross[8]-currentBlock[9][8];     diff += ABS(localDiff);
  552.     localDiff = macross[10]-currentBlock[9][10];     diff += ABS(localDiff);
  553.     localDiff = macross[12]-currentBlock[9][12];     diff += ABS(localDiff);
  554.     localDiff = macross[14]-currentBlock[9][14];     diff += ABS(localDiff);
  555.  
  556.     if ( diff > bestSoFar ) {
  557.     return diff;
  558.     }
  559.  
  560.     macross = &(prev[fy+11][fx]);
  561.  
  562.     localDiff = macross[0]-currentBlock[11][0];     diff += ABS(localDiff);
  563.     localDiff = macross[2]-currentBlock[11][2];     diff += ABS(localDiff);
  564.     localDiff = macross[4]-currentBlock[11][4];     diff += ABS(localDiff);
  565.     localDiff = macross[6]-currentBlock[11][6];     diff += ABS(localDiff);
  566.     localDiff = macross[8]-currentBlock[11][8];     diff += ABS(localDiff);
  567.     localDiff = macross[10]-currentBlock[11][10];     diff += ABS(localDiff);
  568.     localDiff = macross[12]-currentBlock[11][12];     diff += ABS(localDiff);
  569.     localDiff = macross[14]-currentBlock[11][14];     diff += ABS(localDiff);
  570.  
  571.     if ( diff > bestSoFar ) {
  572.     return diff;
  573.     }
  574.  
  575.     macross = &(prev[fy+13][fx]);
  576.  
  577.     localDiff = macross[0]-currentBlock[13][0];     diff += ABS(localDiff);
  578.     localDiff = macross[2]-currentBlock[13][2];     diff += ABS(localDiff);
  579.     localDiff = macross[4]-currentBlock[13][4];     diff += ABS(localDiff);
  580.     localDiff = macross[6]-currentBlock[13][6];     diff += ABS(localDiff);
  581.     localDiff = macross[8]-currentBlock[13][8];     diff += ABS(localDiff);
  582.     localDiff = macross[10]-currentBlock[13][10];     diff += ABS(localDiff);
  583.     localDiff = macross[12]-currentBlock[13][12];     diff += ABS(localDiff);
  584.     localDiff = macross[14]-currentBlock[13][14];     diff += ABS(localDiff);
  585.  
  586.     if ( diff > bestSoFar ) {
  587.     return diff;
  588.     }
  589.  
  590.     macross = &(prev[fy+15][fx]);
  591.  
  592.     localDiff = macross[0]-currentBlock[15][0];     diff += ABS(localDiff);
  593.     localDiff = macross[2]-currentBlock[15][2];     diff += ABS(localDiff);
  594.     localDiff = macross[4]-currentBlock[15][4];     diff += ABS(localDiff);
  595.     localDiff = macross[6]-currentBlock[15][6];     diff += ABS(localDiff);
  596.     localDiff = macross[8]-currentBlock[15][8];     diff += ABS(localDiff);
  597.     localDiff = macross[10]-currentBlock[15][10];     diff += ABS(localDiff);
  598.     localDiff = macross[12]-currentBlock[15][12];     diff += ABS(localDiff);
  599.     localDiff = macross[14]-currentBlock[15][14];     diff += ABS(localDiff);
  600.  
  601.     return diff;
  602. }
  603.  
  604.  
  605. /*===========================================================================*
  606.  *
  607.  * LumMotionErrorD
  608.  *
  609.  *    compute the motion error for the D subsampling pattern
  610.  *
  611.  * RETURNS:    the error, or some number greater if it is worse
  612.  *
  613.  * SIDE EFFECTS:    none
  614.  *
  615.  *===========================================================================*/
  616. int32
  617. LumMotionErrorD(currentBlock, prevFrame, by, bx, my, mx, bestSoFar)
  618.     LumBlock currentBlock;
  619.     MpegFrame *prevFrame;
  620.     int by;
  621.     int bx;
  622.     int my;
  623.     int mx;
  624.     int32 bestSoFar;
  625. {
  626.     register int32    diff = 0;        /* max value of diff is 255*256 = 65280 */
  627.     register int32 localDiff;
  628.     register uint8 *macross;
  629.     register uint8 **prev;
  630.     register int    fy, fx;
  631.     boolean xHalf, yHalf;
  632.  
  633.     xHalf = (ABS(mx) % 2 == 1);
  634.     yHalf = (ABS(my) % 2 == 1);
  635.  
  636.     MOTION_TO_FRAME_COORD(by, bx, my/2, mx/2, fy, fx);
  637.  
  638.     if ( xHalf ) {
  639.     if ( mx < 0 ) {
  640.         fx--;
  641.     }
  642.  
  643.     if ( yHalf ) {
  644.         if ( my < 0 ) {       
  645.         fy--;
  646.         }
  647.         prev = prevFrame->halfBoth;
  648.     } else {
  649.         prev = prevFrame->halfX;
  650.     }
  651.     } else if ( yHalf ) {
  652.     if ( my < 0 ) {
  653.         fy--;
  654.     }
  655.     prev = prevFrame->halfY;
  656.     } else {
  657.     prev = prevFrame->ref_y;
  658.     }
  659.  
  660.     macross = &(prev[fy+1][fx]);
  661.  
  662.     localDiff = macross[1]-currentBlock[1][1];     diff += ABS(localDiff);
  663.     localDiff = macross[3]-currentBlock[1][3];     diff += ABS(localDiff);
  664.     localDiff = macross[5]-currentBlock[1][5];     diff += ABS(localDiff);
  665.     localDiff = macross[7]-currentBlock[1][7];     diff += ABS(localDiff);
  666.     localDiff = macross[9]-currentBlock[1][9];     diff += ABS(localDiff);
  667.     localDiff = macross[11]-currentBlock[1][11];     diff += ABS(localDiff);
  668.     localDiff = macross[13]-currentBlock[1][13];     diff += ABS(localDiff);
  669.     localDiff = macross[15]-currentBlock[1][15];     diff += ABS(localDiff);
  670.  
  671.     if ( diff > bestSoFar ) {
  672.     return diff;
  673.     }
  674.  
  675.     macross = &(prev[fy+3][fx]);
  676.  
  677.     localDiff = macross[1]-currentBlock[3][1];     diff += ABS(localDiff);
  678.     localDiff = macross[3]-currentBlock[3][3];     diff += ABS(localDiff);
  679.     localDiff = macross[5]-currentBlock[3][5];     diff += ABS(localDiff);
  680.     localDiff = macross[7]-currentBlock[3][7];     diff += ABS(localDiff);
  681.     localDiff = macross[9]-currentBlock[3][9];     diff += ABS(localDiff);
  682.     localDiff = macross[11]-currentBlock[3][11];     diff += ABS(localDiff);
  683.     localDiff = macross[13]-currentBlock[3][13];     diff += ABS(localDiff);
  684.     localDiff = macross[15]-currentBlock[3][15];     diff += ABS(localDiff);
  685.  
  686.     if ( diff > bestSoFar ) {
  687.     return diff;
  688.     }
  689.  
  690.     macross = &(prev[fy+5][fx]);
  691.  
  692.     localDiff = macross[1]-currentBlock[5][1];     diff += ABS(localDiff);
  693.     localDiff = macross[3]-currentBlock[5][3];     diff += ABS(localDiff);
  694.     localDiff = macross[5]-currentBlock[5][5];     diff += ABS(localDiff);
  695.     localDiff = macross[7]-currentBlock[5][7];     diff += ABS(localDiff);
  696.     localDiff = macross[9]-currentBlock[5][9];     diff += ABS(localDiff);
  697.     localDiff = macross[11]-currentBlock[5][11];     diff += ABS(localDiff);
  698.     localDiff = macross[13]-currentBlock[5][13];     diff += ABS(localDiff);
  699.     localDiff = macross[15]-currentBlock[5][15];     diff += ABS(localDiff);
  700.  
  701.     if ( diff > bestSoFar ) {
  702.     return diff;
  703.     }
  704.  
  705.     macross = &(prev[fy+7][fx]);
  706.  
  707.     localDiff = macross[1]-currentBlock[7][1];     diff += ABS(localDiff);
  708.     localDiff = macross[3]-currentBlock[7][3];     diff += ABS(localDiff);
  709.     localDiff = macross[5]-currentBlock[7][5];     diff += ABS(localDiff);
  710.     localDiff = macross[7]-currentBlock[7][7];     diff += ABS(localDiff);
  711.     localDiff = macross[9]-currentBlock[7][9];     diff += ABS(localDiff);
  712.     localDiff = macross[11]-currentBlock[7][11];     diff += ABS(localDiff);
  713.     localDiff = macross[13]-currentBlock[7][13];     diff += ABS(localDiff);
  714.     localDiff = macross[15]-currentBlock[7][15];     diff += ABS(localDiff);
  715.  
  716.     if ( diff > bestSoFar ) {
  717.     return diff;
  718.     }
  719.  
  720.     macross = &(prev[fy+9][fx]);
  721.  
  722.     localDiff = macross[1]-currentBlock[9][1];     diff += ABS(localDiff);
  723.     localDiff = macross[3]-currentBlock[9][3];     diff += ABS(localDiff);
  724.     localDiff = macross[5]-currentBlock[9][5];     diff += ABS(localDiff);
  725.     localDiff = macross[7]-currentBlock[9][7];     diff += ABS(localDiff);
  726.     localDiff = macross[9]-currentBlock[9][9];     diff += ABS(localDiff);
  727.     localDiff = macross[11]-currentBlock[9][11];     diff += ABS(localDiff);
  728.     localDiff = macross[13]-currentBlock[9][13];     diff += ABS(localDiff);
  729.     localDiff = macross[15]-currentBlock[9][15];     diff += ABS(localDiff);
  730.  
  731.     if ( diff > bestSoFar ) {
  732.     return diff;
  733.     }
  734.  
  735.     macross = &(prev[fy+11][fx]);
  736.  
  737.     localDiff = macross[1]-currentBlock[11][1];     diff += ABS(localDiff);
  738.     localDiff = macross[3]-currentBlock[11][3];     diff += ABS(localDiff);
  739.     localDiff = macross[5]-currentBlock[11][5];     diff += ABS(localDiff);
  740.     localDiff = macross[7]-currentBlock[11][7];     diff += ABS(localDiff);
  741.     localDiff = macross[9]-currentBlock[11][9];     diff += ABS(localDiff);
  742.     localDiff = macross[11]-currentBlock[11][11];     diff += ABS(localDiff);
  743.     localDiff = macross[13]-currentBlock[11][13];     diff += ABS(localDiff);
  744.     localDiff = macross[15]-currentBlock[11][15];     diff += ABS(localDiff);
  745.  
  746.     if ( diff > bestSoFar ) {
  747.     return diff;
  748.     }
  749.  
  750.     macross = &(prev[fy+13][fx]);
  751.  
  752.     localDiff = macross[1]-currentBlock[13][1];     diff += ABS(localDiff);
  753.     localDiff = macross[3]-currentBlock[13][3];     diff += ABS(localDiff);
  754.     localDiff = macross[5]-currentBlock[13][5];     diff += ABS(localDiff);
  755.     localDiff = macross[7]-currentBlock[13][7];     diff += ABS(localDiff);
  756.     localDiff = macross[9]-currentBlock[13][9];     diff += ABS(localDiff);
  757.     localDiff = macross[11]-currentBlock[13][11];     diff += ABS(localDiff);
  758.     localDiff = macross[13]-currentBlock[13][13];     diff += ABS(localDiff);
  759.     localDiff = macross[15]-currentBlock[13][15];     diff += ABS(localDiff);
  760.  
  761.     if ( diff > bestSoFar ) {
  762.     return diff;
  763.     }
  764.  
  765.     macross = &(prev[fy+15][fx]);
  766.  
  767.     localDiff = macross[1]-currentBlock[15][1];     diff += ABS(localDiff);
  768.     localDiff = macross[3]-currentBlock[15][3];     diff += ABS(localDiff);
  769.     localDiff = macross[5]-currentBlock[15][5];     diff += ABS(localDiff);
  770.     localDiff = macross[7]-currentBlock[15][7];     diff += ABS(localDiff);
  771.     localDiff = macross[9]-currentBlock[15][9];     diff += ABS(localDiff);
  772.     localDiff = macross[11]-currentBlock[15][11];     diff += ABS(localDiff);
  773.     localDiff = macross[13]-currentBlock[15][13];     diff += ABS(localDiff);
  774.     localDiff = macross[15]-currentBlock[15][15];     diff += ABS(localDiff);
  775.  
  776.     return diff;
  777. }
  778.